package com.mystnihon.tdroid.view.fragment;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import org.json.mine.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import ca.benow.transmission.model.TorrentStatus;
import ca.benow.transmission.model.TorrentStatus.TStatus;

import com.actionbarsherlock.app.SherlockListFragment;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.mystnihon.tdroid.R;
import com.mystnihon.tdroid.application.TDroidApplication;
import com.mystnihon.tdroid.config.Config;
import com.mystnihon.tdroid.manager.TransmissionManager;
import com.mystnihon.tdroid.manager.TransmissionManager.TransmissionResult;
import com.mystnihon.tdroid.manager.TransmissionManager.TransmissionResult.ActionType;
import com.mystnihon.tdroid.manager.TransmissionManager.TransmissionResult.ResultType;

public class TorrentFragment extends SherlockListFragment implements Observer {

	private static final String STATE_TORRENTS = "torrents";
	private static final String STATE_LAST_REFRESH_TIME = "lastrefreshTime";
	private static final int MESSAGE_ID = 0;
	private TransmissionManager mManager;
	private ArrayList<TorrentStatus> mTorrents;
	private TorrentListAdapter mTorrentListAdapter;
	private long mLastRefreshTime = 0;
	private long mRefreshTime = 30;
	protected ArrayList<Observable> mLstObservable;
	MenuItem refresh;
	MenuItem upload;
	MenuItem settings;

	public TorrentFragment() {
		mLstObservable = new ArrayList<Observable>();

	}

	@SuppressWarnings("unchecked")
	// It's checked dumbass.
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		mManager = ((TDroidApplication) getSherlockActivity().getApplication()).getAppManager()
				.getTransmissionManager();
		mTorrentListAdapter = new TorrentListAdapter(getSherlockActivity());

		setListAdapter(mTorrentListAdapter);
		getListView().setOnItemLongClickListener(mTorrentListAdapter);
		getListView().setOnItemClickListener(mTorrentListAdapter);

		mLstObservable.add(mManager);

		if (savedInstanceState != null) {
			Object data = savedInstanceState.getSerializable(STATE_TORRENTS);
			if (data != null && data instanceof ArrayList) {
				mTorrents = transform((ArrayList<String>) data);
				mTorrentListAdapter.setTorrents(mTorrents);
			}
			mLastRefreshTime = savedInstanceState.getLong(STATE_LAST_REFRESH_TIME);
		} else {
			mLastRefreshTime = 0;
		}
		if (Config.DEBUG_MODE_ENABLED) {
			Log.d("mLastRefreshTime", "onActiCreated:\t" + mLastRefreshTime);
		}
		setHasOptionsMenu(true);
		getSherlockActivity().setSupportProgressBarIndeterminateVisibility(false);
		super.onActivityCreated(savedInstanceState);
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {

		outState.putSerializable(STATE_TORRENTS, prepareToSerialize(mTorrents));
		outState.putLong(STATE_LAST_REFRESH_TIME, mLastRefreshTime);
		if (Config.DEBUG_MODE_ENABLED) {
			Log.d("mLastRefreshTime", "onSavedIn:\t" + mLastRefreshTime);
		}
		super.onSaveInstanceState(outState);
	}

	@Override
	public void onStart() {
		if (!mManager.hasInitClient() || mManager.IsClientShouldBeInit()) {
			mManager.initTransmissionclient();
			cleanMessages();

		}
		super.onStart();
	}

	@Override
	public void onResume() {
		addObservers();
		if (Config.DEBUG_MODE_ENABLED) {
			Log.d("mLastRefreshTime", "onResume:\t" + mLastRefreshTime);
		}
		final long remaining = mLastRefreshTime + mRefreshTime * 1000L - System.currentTimeMillis();
		if (remaining < 0) {
			refresh();
		} else {
			setNextRefresh(remaining);
		}
		super.onResume();
	}

	@Override
	public void onPause() {
		cleanMessages();
		removeObservers();
		super.onPause();
	}

	public void refresh() {
		if (Config.DEBUG_MODE_ENABLED) {
			Log.d("mLastRefreshTime", "Launch refresh");
		}
		if (isAdded()) {
			if (mManager.hasInitClient()) {
				getSherlockActivity().setSupportProgressBarIndeterminateVisibility(true);
				mManager.getTorrentList();

			}
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void update(Observable observable, Object data) {

		if (observable instanceof TransmissionManager) {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(false);
			TransmissionResult result = (TransmissionResult) data;
			if (result.mAction == ActionType.GetTorrent) {
				mLastRefreshTime = System.currentTimeMillis();
				if (Config.DEBUG_MODE_ENABLED) {
					Log.d("mLastRefreshTime", "update:\t" + mLastRefreshTime);
				}
				setNextRefresh(mRefreshTime * 1000);
			} else {
				cleanMessages();
				setNextRefresh(500);
			}
			if (ResultType.SUCCESS == result.mSuccess && result.mAction == ActionType.GetTorrent) {
				mTorrents = (ArrayList<TorrentStatus>) result.mData;
				mTorrentListAdapter.setTorrents(mTorrents);
			}
		}

	}

	protected void addObservers() {
		for (final Observable obs : mLstObservable) {
			obs.addObserver(this);
		}
	}

	protected void removeObservers() {
		for (final Observable obs : mLstObservable) {
			obs.deleteObserver(this);
		}
	}

	Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			if (msg.what == MESSAGE_ID) {
				Log.d("mLastRefreshTime", "Handle message");
				refresh();
			}
			// super.handleMessage(msg);
		};

	};

	private void cleanMessages() {
		if (mHandler.hasMessages(MESSAGE_ID)) {
			mHandler.removeMessages(MESSAGE_ID);
		}
	}

	private void setNextRefresh(long time) {
		cleanMessages();
		mHandler.sendEmptyMessageDelayed(MESSAGE_ID, time);
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

		refresh = menu.add(0, 1, 1, R.string.action_refresh).setIcon(R.drawable.ic_menu_refresh)
				.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM)
				.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {

					public boolean onMenuItemClick(MenuItem item) {
						refresh();
						return false;
					}
				});

		upload = menu.add(0, 2, 2, R.string.action_add_a_torrent).setIcon(R.drawable.ic_menu_upload)
				.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);

		// settings = menu.add(0, 3, 3, R.string.action_settings).setIcon(android.R.drawable.ic_menu_preferences)
		// .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

		super.onCreateOptionsMenu(menu, inflater);
	}

	class TorrentListAdapter extends BaseAdapter implements OnItemClickListener, OnItemLongClickListener {
		ArrayList<TorrentStatus> torrents;
		LayoutInflater inflater;
		Activity mActivity;

		class ViewHolder {
			TextView mTextView;
			ProgressBar mProgressBar;
			ImageView mToggleButton;

		}

		public void setTorrents(ArrayList<TorrentStatus> torrentss) {
			torrents = torrentss;
			notifyDataSetChanged();
		}

		public TorrentListAdapter(Activity activity) {
			torrents = new ArrayList<TorrentStatus>();
			mActivity = activity;
			inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		@Override
		public int getCount() {
			return torrents.size();
		}

		@Override
		public TorrentStatus getItem(int position) {
			return torrents.get(position);
		}

		@Override
		public long getItemId(int position) {
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if (convertView == null) {
				holder = new ViewHolder();
				convertView = inflater.inflate(R.layout.listitem_torrents, null);
				holder.mTextView = (TextView) convertView.findViewById(R.id.listitem_torrent_title);
				holder.mProgressBar = (ProgressBar) convertView.findViewById(R.id.listitem_torrent_progress);
				holder.mToggleButton = (ImageView) convertView.findViewById(R.id.listitem_torrent_resume_pause);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}
			TorrentStatus torrentstatus = getItem(position);
			TStatus status = torrentstatus.getStatus();
			holder.mTextView.setText(torrentstatus.getName());
			Number percent = torrentstatus.getPercentDone() * 100;
			holder.mProgressBar.setProgress(percent.intValue());
			if (status == TStatus.Downloading || status == TStatus.Checking || status == TStatus.Seeding) {
				holder.mToggleButton.setImageResource(R.drawable.ic_media_pause);
			} else {
				holder.mToggleButton.setImageResource(R.drawable.ic_media_play);
			}

			return convertView;
		}

		@Override
		public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
			TorrentStatus torrentstatus = getItem(position);
			getSherlockActivity().startActionMode(new TorrentActionModes(torrentstatus.getId()));
			return true;
		}

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

			Toast.makeText(getSherlockActivity(), "Click on list item " + position, Toast.LENGTH_SHORT).show();
		}

	}

	private ArrayList<String> prepareToSerialize(ArrayList<TorrentStatus> arrayList) {
		final ArrayList<String> jsonArray = new ArrayList<String>();

		for (TorrentStatus string : arrayList) {
			jsonArray.add(string.toString());
		}
		return jsonArray;
	}

	private ArrayList<TorrentStatus> transform(ArrayList<String> fromSerializeJson) {
		final ArrayList<TorrentStatus> tStatusArray = new ArrayList<TorrentStatus>();
		for (String json : fromSerializeJson) {
			tStatusArray.add(new TorrentStatus(new JSONObject(json)));
		}
		return tStatusArray;
	}

	private void deleteATorrent(int torrentId) {
		AlertDialog.Builder builder = new AlertDialog.Builder(getSherlockActivity());
		LayoutInflater inflater = (LayoutInflater) getSherlockActivity().getSystemService(
				Context.LAYOUT_INFLATER_SERVICE);
		final View v = inflater.inflate(R.layout.layout_dialog_delete, null);
		CheckBox checkbox = (CheckBox) v.findViewById(R.id.diag_checkbox);
		checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				// TODO Auto-generated method stub

			}

		});
		builder.setTitle(R.string.dialog_delete_torrent_title).setView(v)
				.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub

					}
				}).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub

					}
				}).show().setCancelable(true);
	}

	private final class TorrentActionModes implements ActionMode.Callback {
		int mSelectedItem = 0;
		final int PLAY = Menu.FIRST;
		final int PAUSE = PLAY + 1;
		final int DELETE = PAUSE + 1;

		public TorrentActionModes(int selectedItem) {
			super();
			mSelectedItem = selectedItem;
		}

		@Override
		public boolean onCreateActionMode(ActionMode mode, Menu menu) {

			menu.add(0, PLAY, 1, R.string.action_play).setIcon(R.drawable.ic_media_play)
					.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);

			menu.add(0, PAUSE, 2, R.string.action_pause).setIcon(R.drawable.ic_media_pause)
					.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);

			menu.add(0, DELETE, 3, R.string.action_delete).setIcon(R.drawable.ic_menu_close_clear_cancel)
					.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);

			return true;
		}

		@Override
		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
			return false;
		}

		@Override
		public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
			handlerAction(item.getItemId());
			mode.finish();
			return true;
		}

		@Override
		public void onDestroyActionMode(ActionMode mode) {
		}

		private void handlerAction(int menuId) {
			switch (menuId) {
			case PLAY:
				mManager.startTorrent(mSelectedItem);
				break;
			case PAUSE:
				mManager.stopTorrent(mSelectedItem);
				break;
			case DELETE:
				deleteATorrent(mSelectedItem);
				break;

			default:
				Toast.makeText(getSherlockActivity(), "Action unknown", Toast.LENGTH_SHORT).show();
				break;
			}
		}
	}
}
